/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2012/07/11
* File: CameraSceneNode.h
* Blog: http://www.cnblogs.com/zengqh/
**/

#ifndef CameraSceneNode_h__
#define CameraSceneNode_h__

#include "../Core/Core.h"
#include "../Core/Declare.h"
#include "SceneNode.h"

class CameraSceneNode : public SceneNode
{
public:
	CameraSceneNode(SceneNode* parent, 
		SceneManager* scene_mgr, 
		s32 id = -1,
		s32 type = 0,
		const glm::vec3& position = glm::vec3(0.0f, 0.0f, 0.0f));

	~CameraSceneNode();

	/* can not declare const */
	virtual const glm::mat4& getProjMatrix();

	virtual const glm::mat4& getViewMatrix();

	virtual const glm::mat4& getViewProjMatrix();

	virtual const glm::vec3& getEyePos() const;
	virtual void setEyePos(const glm::vec3& eye_pos);
	
	virtual const glm::vec3& getTargetPos() const;
	virtual void setTargetPos(const glm::vec3& target_pos);

	virtual const glm::vec3& getUpVector() const;
	virtual void setUpVector(const glm::vec3& up_vector);

	virtual void lookAt(
		const glm::vec3& eye_pos, 
		const glm::vec3& target_pos,
		const glm::vec3& up_vector);

	virtual void setPerspectiveFov(f32 fov, f32 aspect, f32 near_plane, f32 far_plane);

	virtual f32 getNearPlane() const;
	virtual f32 getFarPlane() const;

	virtual void yaw(f32 angle);
	virtual void pitch(f32 angle);
	virtual void roll(f32 angle);
	virtual void move(f32 distance);
	virtual void moveLR(f32 distance);
	virtual void yawTarget(f32 angle);

	void render();

protected:
	virtual void setViewDirty();
	virtual void setProjDirty();

protected:
	glm::mat4				_view_matrix;
	glm::mat4				_proj_matrix;
	glm::mat4				_view_proj_matrix;

	glm::vec3				_eye_pos;
	glm::vec3				_target_pos;
	glm::vec3				_up_vector;

	f32						_fov;
	f32						_aspect;
	f32						_near_plane;
	f32						_far_plane;

	bool					_view_matrix_dirty;
	bool					_proj_matrix_dirty;
	bool					_view_proj_matrix_dirty;

	f32						_camera_vertical_angle;
};
#endif    /* CameraSceneNode_h__ */